package com.example.shiyansan.service.impl;

import com.example.shiyansan.entity.Book;
import com.example.shiyansan.entity.Cart;
import com.example.shiyansan.entity.User;
import com.example.shiyansan.mapper.*;
import com.example.shiyansan.service.CartService;
import com.example.shiyansan.vo.CartVo;
import com.example.shiyansan.vo.OrderVo;
import com.example.shiyansan.vo.OrderVo.OrderDetailVo;
import com.sun.jdi.LongValue;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import static com.example.shiyansan.interceptor.JwtTokenInterceptor.THREAD_LOCAL;

@Service
public class CartServiceImpl implements CartService {
    /**
     * 添加图书
     * @param bookId
     */
    @Autowired
    private CartMapper cartMapper;

    @Autowired
    private BookMapper bookMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Transactional
    @Override
    public void add(int bookId,int quantity) throws Exception {
       //首先判断用户是否登录
        Long userId = (Long) THREAD_LOCAL.get();
        if(userId == null){
            throw new Exception("用户未登录");
        }
        //首先判断该用户的购物车中是否有该图书
        Cart cart = cartMapper.findByBookIdAndUserId(bookId, userId);
        //如果有则数量加一
        if(cart!=null){
            cart.setQuantity(cart.getQuantity()+quantity);
            cartMapper.update(cart);
        }else{
            //如果没有则将该图书的信息插入到购物车中
            //TODO Cart实体中包含了完整的User和Book对象，但数据库只存储ID，mybatis映射复杂化
            Cart cart1 = new Cart();
            User user = new User();
            user.setUserId(userId.intValue());
            Book book = new Book();
            book.setBookId(bookId);
            cart1.setUser(user);
            cart1.setBook(book);
            cart1.setQuantity(quantity);
            cartMapper.insert(cart1);
        }
    }

    /**
     * 修改图书数量
     * @param cart
     */
    @Transactional
    @Override
    public void update(Cart cart) throws Exception {
//        首先判断当前用户和修改购物车中数量的人是否一致
        Long userId = (long) cart.getUser().getUserId();
        // 设置用户ID到购物车对象
        User user = new User();
        user.setUserId(userId.intValue());
        cart.setUser(user);
        if(userId == null && !userId.equals(THREAD_LOCAL.get())) {
            throw new Exception("你无权修改数量");
        }
        int bookId = cart.getBook().getBookId();

        //首先对修改的库存数量进行判断，必须大于1小于100
        if(cart.getQuantity()<0||cart.getQuantity()>100){
            throw new Exception("修改的库存数量必须大于1小于100");
        }

        //判断你修改的数量是否大于库存数
        int stock = bookMapper.findBookStock(bookId);
        if(stock < cart.getQuantity()){
            throw new Exception("库存不足");
        }
        cartMapper.update(cart);
//        Cart cart1 = new Cart();
//        cart1.setUser(user);
//        cartMapper.list(cart);
    }

    /**
     * 删除图书
     * @param bookId
     */
    @Override
    public void delete(int bookId) throws Exception {
        cartMapper.delete(bookId, (Long) THREAD_LOCAL.get());
    }

    /**
     * 查看购物车列表
     * @return
     */
    @Override
    public List<CartVo> list() {
        //通过用户id来查找对应的购物车列表
        User user = new User();
        Long userId = (Long) THREAD_LOCAL.get();
        user.setUserId(userId.intValue());
        Cart cart = Cart.builder()
                .user(user).build();
        List<CartVo> cartVoList = cartMapper.list(cart);
        //手动计算总金额
        for (CartVo cartVo:cartVoList
             ) {
            Double sum = 0d;
            for (CartVo.CartItem ca: cartVo.getCartItemList()
                 ) {
               sum =  ca.getQuantity() * ca.getPrice();
               cartVo.setSum(sum);
            }
        }
        return cartVoList;
    }

    /**
     * 结算购物车，生成订单
     */
    @Transactional
    @Override
    public void submit(Integer cartId) throws Exception {
        //通过用户id和传入的某个购物车的id来获取用户想要结算的购物车
        Long userId = (Long) THREAD_LOCAL.get();
        User user = new User();
        user.setUserId(userId.intValue());

        //判断用户是否指定了购物车id，如果没指定则是结算全部购物车
        //TODO 多一个限制条件反而可以查到记录，少一个限制条件查不到记录了
        Cart cart;
        if(cartId == null){
             cart = Cart.builder()
                    .user(user)
                    .build();
        }else {
             cart = Cart.builder()
                    .user(user)
                    .cartId(cartId)
                    .build();
        }
        //此时这个购物车列表应该只有一条记录
        List<CartVo> list = cartMapper.list(cart);
        //判断购物车是否为null
        if(list == null || list.size() == 0){
            throw new Exception("购物车为空");
        }

        //创建订单,属性不完全，但是为了主键回写获取id
        OrderVo orderVo = new OrderVo();
        orderVo.setCreateTime(LocalDateTime.now());
        orderVo.setStatus("0");
        orderVo.setUsername(userMapper.findByUserId(userId));
        orderVo.setUserId(userId.intValue());
        //插入订单记录
        orderMapper.insert(orderVo);


        //订单对订单详情表1对多，购物车对购物车下单项是1对多
        //获取订单详情列表
        Double totalPrice = 0d;
        int stock = 0;
        //拷贝属性，获得订单详情表列表
        List<OrderDetailVo> orderDetailVoList = new ArrayList<>();
        for (CartVo cartvo:list
             ) {
            for (CartVo.CartItem ca: cartvo.getCartItemList()
                 ) {
                OrderDetailVo orderDetailVo = new OrderDetailVo();
                BeanUtils.copyProperties(ca, orderDetailVo);
                totalPrice += ca.getQuantity() * ca.getPrice();
                //计算需要扣减的库存数目
                stock = ca.getQuantity();
                //设置订单id
                orderDetailVo.setOrderId(orderVo.getOrderId());
                //将购物车中的图书列表全部拷贝到订单详情表中
                orderDetailVoList.add(orderDetailVo);
                //找到对应的图书，扣减库存
                Book book = bookMapper.findBookById(ca.getBookId());
                book.setStock(book.getStock() - stock);
                bookMapper.updateStock(book);
            }
        }

        orderVo.setTotalPrice(totalPrice);
        orderVo.setStatus("1");
        orderMapper.update(orderVo);

        //插入对应订单详情页的记录
        orderDetailMapper.insertBatch(orderDetailVoList);

        //TODO 清空购物车
        Cart cart1 = new Cart();
        cart1.setUser(user);
        cartMapper.deleteByCart(cart1);
    }
}
